using System.Collections.Generic;
using System.Linq;
using CustomerContactSystem.Core.Infrastructure.Domain;

namespace CustomerContactSystem.Core.Model {
    public class User : Entity {
        public virtual Department Department { get; set; }
        public virtual UserGroup UserGroup { get; set; }
        public virtual string Username { get; set; }
        public virtual string Password { get; set; }
        public virtual string PasswordMatch { get; set; }
        public virtual string Email { get; set; }
        public virtual string DisplayName { get; set; }
        public virtual bool FirstPointOfContact { get; set; }
        public virtual string AreaCovered { get; set; }
        public virtual bool IsActive { get; set; }
        private readonly ICollection<UserRole> _roles;
        public virtual IEnumerable<UserRole> Roles { get { return _roles.Select(x => x); } } 

        public User() {
            _roles = new HashSet<UserRole>();
        }

        public virtual bool IsInRole(string roleName) {
            var foundRole = Roles.SingleOrDefault(r => r.RoleName == roleName);
            return foundRole != null;
        }

        public virtual bool IsInRoleLike(string roleName) {
            var roles = Roles.ToList();
            return roles.Any(userRole => userRole.RoleName.Contains(roleName));
        }

        public virtual void AddRole(UserRole role) {
            if (!_roles.Contains(role)) {
                _roles.Add(role);   
            }
        }

        public virtual void RemoveRole(UserRole role) {
            _roles.Remove(role);
        }

        public virtual bool IsSubmitterRefereeOrAdminOver(int submittedById, int submittedByGroupId, int submittedByDepartmentId, int currentRefId, int currentRefGroupId, int currentRefDepartmentId) {
            if (IsInRole("System Admin")) {
                return true;
            }

            if (submittedById == Id) {
                return true;
            }

            if (currentRefId == Id) {
                return true;
            }

            if (IsInRoleLike("Admin")) {
                if (submittedByGroupId == UserGroup.Id || currentRefGroupId == UserGroup.Id) {
                    return true;
                }

                if (submittedByDepartmentId == Department.Id || currentRefDepartmentId == Department.Id) {
                    return true;
                }
            }
            return false;
        }

        protected override void Validate() {
            if (Department == null || Department.Id == 0) {
                AddBrokenRule(new BusinessRule("Department", "Please select a department!"));
            }

            if (UserGroup == null || UserGroup.Id == 0) {
                AddBrokenRule(new BusinessRule("Group", "Please select a group!"));
            }

            if (string.IsNullOrEmpty(Username)) {
                AddBrokenRule(new BusinessRule("Username", "Username is required!"));
            }

            if (string.IsNullOrEmpty(Password)) {
                AddBrokenRule(new BusinessRule("Password", "Password is required"));
            }

            if (Password != PasswordMatch) {
                AddBrokenRule(new BusinessRule("Password", "Passwords do not match"));
            }
            if (string.IsNullOrEmpty(Email)) {
                AddBrokenRule(new BusinessRule("Email", "Email is required!"));
            }

            if (string.IsNullOrEmpty(DisplayName)) {
                AddBrokenRule(new BusinessRule("DisplayName", "Display name is required!"));
            }
        }
    }
}